home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Loadstar 145
/
145.d81
/
t.disc e
< prev
next >
Wrap
Text File
|
2022-08-26
|
24KB
|
1,033 lines
A complete dissection of Gfx-Zone
by XmikeX
[Note from Jeff:] some of this
listing may not print properly in the
6-column mode.
The following is a disassembly of
the ML code itself. Although I won't
go through it 100% step by step,
important points shall be perused for
the purposes of clarification, and to
be honest, for a little self-
introspection on my part.
The program starts out quite simply
with the start address and a
labelling of important memory
locations (generally used as pointers
throughout the program).
;--------------------------------
*= $c000; start of program
;--------------------------------
point = $fb ; LSB = point ($fb)
; MSB = point+1 ($fc)
temp = $cfff ; MSB byte storage
temp2 = $cffe ; used by FLD routine
temp3 = $cffd ; $cffa/cffb for
; TBB/AMJ player uses these.
looper = $ccfc ; see pause routine
hit = $ccf9 ; see pause routine
;----------------------------------
init lda #$36 ; #$36 is our
;kill-basic value, so
sta $01 ; store the kill-basic value
into $01 and move the
; basic rom out of the way,
exposing the ram underneath.
[AssEd. Note : For general
edification, location $01 works as
follows in C64]
[ - bit 0: ROM/RAM at $a000 1=Basic
0=RAM]
[ - bit 1: ROM/RAM at $e000 1=Kernal
0=RAM]
[ - bit 2: ROM or I/O block 1=I/O
0=ROM]
[ - bits 3,4,5 are cassette
related........]
[ - bits 6 & 7 are not connected in
the C64]
[ - bit 6 checks the status of the
caps lock (ascii/cc) key on C128.]
lda #$00 ; ok...set up accumulator
as #$00
sta $d020; change screen and
sta $d021; border to black (i.e.,
#$00)
sta point; store LSB of pointer
(which is now #$00)
lda #$00 ; initialize the looper
sta looper
Ok... So what is going on here?
Basically, we are telling Basic to
take a hike so that we can use the
memory it once inhabited. We are also
setting up the LEAST SIGNIFICANT BYTE
pointer for the indirect Y function.
This is a powerful tool in 6502
assembly and we will get to it later
:). The "looper" is just a memory
location that the program will use in
its "pause" subroutine. Right now, it
is set at zero (#$00).
UGLY lda #$fa ; try and tell
tbb/amj music player
sta $105b; what scanline to play
at
amjtune jsr $1000; jsr call to
sys4096/amj's TBB player at $1000
This part is really UGLY.
Basically, I tried to extract the
music player and tried to incorporate
it here, but I failed for some
unknown reason. I decided that since
it was proving to be uncooperative
that I should just call it from here
and let it go off on its own. This
presented two problems for me later.
The first was that the music was
playing at raster lines that were
outside the border area. In layman's
terms this means that it would play
in the middle of the screen and a
slight flicker could be seen as the
main code flipped through the pics. I
rectified the situation by finding
out where it was polling its raster
info ($105b) and sticking an #$fa in
there. #$fa is raster line 250, which
should correspond to the lower border
on the screen. Yes, I could have
modified the player code itself, but
I was getting a bit paranoid at this
juncture and decided not to modify
it. The second problem is that by
giving up control to the player
subroutine, I lost control of timing,
an annoyance that which we shall
discuss later. Anyways, as you can
see I call the player in the
'amjtune' subroutine and let it do
its thing, but even though it is not
in the main code, I've included the
player here for the benefit of the
reader. As this code is from someone
else, I cannot assure a 100% correct
disassembly, but read on..
TBB player from SYS4096 tune by
AMJ starts at $1000 and proceeds as
follows: (By the way, TBB is AMJ's
brother...trivia mode over).
<start of player code>
> sei ; disables interrupts
> lda #$01
> sta $d01a ; set up for scan line
> lda #$7f
> sta $dc0d ; enable timer interpts
> lda #$35 ; lets play with roms
> sta $01
> lda #$00
> ldx #$00
> ldy #$00
> jsr $1100 ; jsr to musix init ?
> lda #$37 ; let's play with roms
> sta $01
> lda #<irq ; LSB of irq
> sta $0314 ; stash it
> lda #>irq
> sta $0315 ; MSB of irq
> lda #$3a
> sta $d012
> lda #$1b ; normalize the screen i
think
> sta $d011
> cli ; re-enables interrupts
> rts ; it used to jmp back to
itself, infinite loop
> ; as its irq routine played in the
backgroud
>irq lda #$01 ; the irq routine
> sta $d019
> lda #$35 ; let's play with roms
again
> sta $01
> dec $d020
> jsr $1103 ; $1103 (!) I think this
jsr's to musix data
> inc $d020
> lda #$37 ; let's play with roms
yet again
> sta $01
> inc selfmod+1 ; self-modifying
code!!!
>selfmod lda #$xx ; #$xx = this is
the byte changed by 'inc selfmod+1'
> and #$01
> tax
> lda #$105b,x ; goes to the scan
line table ?
> sta $d012 ; sets up the scan line
for irq to occur
> jmp $ea31 ; go to normal c= irq
return
<end of player code>
From $105c to $10a0 or so beyond
this there is some program data of
unknown function. At around $1100
there is an embedded message by the
authors and then the music data
follows, ending somewhere around
$26b0 if I recall correctly. Please
note that this tune is double-speed
(i.e., plays twice per frame).
<back to main program code>
The initialization steps have
executed and the music player has
been told to start playing. What is
left now is to present the C/G
pictures to the viewer in a
meaningful way.
The main1 routine that follows
conducts the sequence of the C/G
displays. Its responsibility is to
load and store the MOST SIGNIFICANT
BYTE of the address (location) of
each starting pic for a given pattern
of displays and then branch out to
the pattern subroutines, which
display c/g pics sequentially given a
predetermined sequence. Again, the
MSB as with the LSB we encountered
earlier deals with the indirect Y
function that we shall explore
later.
main1 lda #$30 ; starting pic MSB
sta temp ; store MSB in temp
jsr pattern
lda #$30 ; starting pic MSB
sta temp ; store MSB in temp
jsr pattern0
lda #$c0 ; this MSB is being stored
but pattern1 does not use it
sta temp
jsr pattern2
jsr pattern1; fld bounce of the
first intro pic only
; located at $3000-$37e7
; fld effect is quite annoying, so
its done only once
lda #$38
sta temp
jsr p0 ; p0 routine is a part
(subset) of pattern0 routine
lda #$c0 ; the rest of these are
more of the same... calls to
sta temp ; pattern subroutines
jsr pattern2
lda #$38
sta temp
jsr pattern0
lda #$c0
sta temp
jsr pattern2
lda #$30
sta temp
jsr pattern0
lda #$c0
sta temp
jsr pattern2
lda #$30
sta temp
jsr pattern0
lda #$c0
sta temp
jsr pattern2
lda #$38
sta temp
jsr p0
lda #$c0
sta temp
jsr pattern2
lda #$38
sta temp
jsr p0
lda #$c0
sta temp
jsr pattern2
jsr pattern3; last pattern before
music loops back on itself
jmp main1
By now, music has looped...time to
slow down again with the original
pattern at the start of main1 routine
(i.e., pattern routine that follows
is called at the start of main1)
"pattern" is the first of the
pattern subroutines. Its
responsibility is to take care of the
first and second intro pics at the
start of the program. It pulls the
MSB from the temp memory location
(the first intro pic), jsrs to the
viewpic routine, and loads a "hit"
value which the "pause" routine
will then compare with an "looper"
value. This determines how long the
first intro pic will be shown. After
which, "pattern" will change the MSB
value (without affecting the MSB in
temp) to point to the second intro
pic, and then it repeats this process
until the music tempo increases, upon
which time "pattern" gives up control
to another "patternX" subroutine.
I mentioned earlier that I lost
control of timing when I gave up some
control to the music player code.
That is to say, because I could not
(at the time) incorporate the player
code in here, I had no way of
properly synching the pictures to the
beat of the music as it played. I
corrected this deficiency in true
'newbie' fashion. I used delay loops
to form the core basis of what I
could ap